from datetime import datetime
from typing import List, Tuple, Optional, Dict, Any
from dataclasses import dataclass, asdict
import json
from decimal import Decimal
from peewee import *
from config.config import Config
import logging
from exception.base_exceptions import DataProcessingException
from exception.exception_handler import global_exception_handler

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 数据库连接 - 使用与brain_wave_model.py相同的配置
database = MySQLDatabase(
    Config.database, 
    host=Config.host, 
    user=Config.user, 
    password=Config.password,
    charset='utf8mb4')


@dataclass
class SleepMonitoringRecordSummary:
    """睡眠监测记录摘要信息"""
    dominant_state: str
    avg_confidence: float
    deep_sleep_duration: int
    light_sleep_duration: int
    awake_duration: int
    description: str = ""


@dataclass
class SleepMonitoringRecordData:
    """睡眠监测记录详细数据"""
    states: List[Tuple[int, str]]
    confidence: List[Tuple[int, float]]
    delta_ratio: List[Tuple[int, float]]
    theta_ratio: List[Tuple[int, float]]
    alpha_ratio: List[Tuple[int, float]]
    beta_ratio: List[Tuple[int, float]]
    gamma_ratio: List[Tuple[int, float]]


@dataclass
class SleepMonitoringRecord:
    """睡眠监测记录完整数据模型"""
    session_id: str
    start_time: datetime
    end_time: datetime
    total_seconds: int
    summary: SleepMonitoringRecordSummary
    data: SleepMonitoringRecordData
    id: Optional[int] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        result = {
            "session_id": self.session_id,
            "start_time": self.start_time.isoformat() if self.start_time else None,
            "end_time": self.end_time.isoformat() if self.end_time else None,
            "total_seconds": self.total_seconds,
            "summary": {
                "dominant_state": self.summary.dominant_state,
                "avg_confidence": self.summary.avg_confidence,
                "deep_sleep_duration": self.summary.deep_sleep_duration,
                "light_sleep_duration": self.summary.light_sleep_duration,
                "awake_duration": self.summary.awake_duration,
                "description": self.summary.description
            },
            "data": {
                "states": self.data.states,
                "confidence": self.data.confidence,
                "delta_ratio": self.data.delta_ratio,
                "theta_ratio": self.data.theta_ratio,
                "alpha_ratio": self.data.alpha_ratio,
                "beta_ratio": self.data.beta_ratio,
                "gamma_ratio": self.data.gamma_ratio
            }
        }
        
        if self.id:
            result["id"] = self.id
        if self.created_at:
            result["created_at"] = self.created_at.isoformat()
        if self.updated_at:
            result["updated_at"] = self.updated_at.isoformat()
            
        return result

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'SleepMonitoringRecord':
        """从字典创建实例"""
        summary_data = data.get('summary', {})
        session_data = data.get('data', {})
        
        summary = SleepMonitoringRecordSummary(
            dominant_state=summary_data.get('dominant_state', ''),
            avg_confidence=summary_data.get('avg_confidence', 0.0),
            deep_sleep_duration=summary_data.get('deep_sleep_duration', 0),
            light_sleep_duration=summary_data.get('light_sleep_duration', 0),
            awake_duration=summary_data.get('awake_duration', 0),
            description=summary_data.get('description', '')
        )
        
        session_detail_data = SleepMonitoringRecordData(
            states=session_data.get('states', []),
            confidence=session_data.get('confidence', []),
            delta_ratio=session_data.get('delta_ratio', []),
            theta_ratio=session_data.get('theta_ratio', []),
            alpha_ratio=session_data.get('alpha_ratio', []),
            beta_ratio=session_data.get('beta_ratio', []),
            gamma_ratio=session_data.get('gamma_ratio', [])
        )
        
        return cls(
            session_id=data['session_id'],
            start_time=datetime.fromisoformat(data['start_time'].replace('Z', '+00:00')) if data.get('start_time') else None,
            end_time=datetime.fromisoformat(data['end_time'].replace('Z', '+00:00')) if data.get('end_time') else None,
            total_seconds=data['total_seconds'],
            summary=summary,
            data=session_detail_data,
            id=data.get('id'),
            created_at=datetime.fromisoformat(data['created_at'].replace('Z', '+00:00')) if data.get('created_at') else None,
            updated_at=datetime.fromisoformat(data['updated_at'].replace('Z', '+00:00')) if data.get('updated_at') else None
        )


class SleepMonitoringRecordModel(Model):
    """睡眠监测记录Peewee模型"""
    
    id = AutoField(primary_key=True)
    session_id = CharField(unique=True, max_length=100, null=False)
    start_time = DateTimeField(null=False)
    end_time = DateTimeField(null=False)
    total_seconds = IntegerField(null=False)
    summary_data = TextField(null=False)  # JSON格式存储summary
    record_data = TextField(null=False)   # JSON格式存储data
    created_at = DateTimeField(default=datetime.now)
    updated_at = DateTimeField(default=datetime.now)
    
    class Meta:
        database = database
        table_name = 'sleep_monitoring_records'

class SleepMonitoringRecordRepository:
    """睡眠监测记录仓库类"""
    
    def __init__(self):
        pass
    
    def create_record(self, record: SleepMonitoringRecord) -> int:
        """创建睡眠监测记录"""
        summary_json = json.dumps(asdict(record.summary), ensure_ascii=False)
        data_json = json.dumps(asdict(record.data), ensure_ascii=False)
        
        sleep_record = SleepMonitoringRecordModel.create(
            session_id=record.session_id,
            start_time=record.start_time,
            end_time=record.end_time,
            total_seconds=record.total_seconds,
            summary_data=summary_json,
            record_data=data_json
        )
        
        return sleep_record.id
    
    def get_record_by_id(self, session_id: str) -> Optional[SleepMonitoringRecord]:
        """根据session_id获取睡眠监测记录"""
        try:
            sleep_record = SleepMonitoringRecordModel.get(
                SleepMonitoringRecordModel.session_id == session_id
            )
            return self._model_to_record(sleep_record)
        except SleepMonitoringRecordModel.DoesNotExist:
            return None
    
    def get_all_records(self, limit: int = 50, offset: int = 0) -> List[SleepMonitoringRecord]:
        """获取所有睡眠监测记录列表"""
        sleep_records = (SleepMonitoringRecordModel
                        .select()
                        .order_by(SleepMonitoringRecordModel.start_time.desc())
                        .limit(limit)
                        .offset(offset))
        
        records = []
        for sleep_record in sleep_records:
            record = self._model_to_record(sleep_record)
            if record:
                records.append(record)
        
        return records
    
    def update_description(self, session_id: str, description: str) -> bool:
        """更新睡眠监测记录的描述"""
        try:
            sleep_record = SleepMonitoringRecordModel.get(
                SleepMonitoringRecordModel.session_id == session_id
            )
            # 更新summary中的description
            summary_data = json.loads(sleep_record.summary_data)
            summary_data['description'] = description
            sleep_record.summary_data = json.dumps(summary_data, ensure_ascii=False)
            sleep_record.updated_at = datetime.now()
            sleep_record.save()
            return True
        except SleepMonitoringRecordModel.DoesNotExist:
            return False
    
    def delete_record(self, session_id: str) -> bool:
        """删除睡眠监测记录"""
        try:
            sleep_record = SleepMonitoringRecordModel.get(
                SleepMonitoringRecordModel.session_id == session_id
            )
            sleep_record.delete_instance()
            return True
        except SleepMonitoringRecordModel.DoesNotExist:
            return False
    
    def _model_to_record(self, model: SleepMonitoringRecordModel) -> SleepMonitoringRecord:
        """将Peewee模型转换为SleepMonitoringRecord对象"""
        try:
            # 解析JSON数据
            summary_data = json.loads(model.summary_data)
            data_json = json.loads(model.record_data)
            
            # 创建数据对象
            data = SleepMonitoringRecordData(
                states=data_json.get('states', []),
                confidence=data_json.get('confidence', []),
                delta_ratio=data_json.get('delta_ratio', []),
                theta_ratio=data_json.get('theta_ratio', []),
                alpha_ratio=data_json.get('alpha_ratio', []),
                beta_ratio=data_json.get('beta_ratio', []),
                gamma_ratio=data_json.get('gamma_ratio', [])
            )
            
            # 创建摘要对象
            summary = SleepMonitoringRecordSummary(
                dominant_state=summary_data.get('dominant_state', ''),
                avg_confidence=summary_data.get('avg_confidence', 0.0),
                deep_sleep_duration=summary_data.get('deep_sleep_duration', 0),
                light_sleep_duration=summary_data.get('light_sleep_duration', 0),
                awake_duration=summary_data.get('awake_duration', 0),
                description=summary_data.get('description', '')
            )
            
            # 创建完整记录对象
            return SleepMonitoringRecord(
                id=model.id,
                session_id=model.session_id,
                start_time=model.start_time,
                end_time=model.end_time,
                total_seconds=model.total_seconds,
                summary=summary,
                data=data,
                created_at=model.created_at,
                updated_at=model.updated_at
            )
        except (json.JSONDecodeError, KeyError) as e:
            exception = DataProcessingException(f"解析睡眠监测记录数据失败，会话ID: {model.session_id}，错误详情: {str(e)}")
            global_exception_handler.handle_exception(exception)
            return None


# 使用示例
if __name__ == "__main__":
    from datetime import timedelta
    
    # 初始化数据库连接
    database.connect()
    
    # 创建表（如果不存在）
    database.create_tables([SleepMonitoringRecordModel], safe=True)
    
    # 创建仓库实例
    repo = SleepMonitoringRecordRepository()
    
    # 创建示例数据
    summary = SleepMonitoringRecordSummary(
        dominant_state="deep_sleep",
        avg_confidence=0.85,
        deep_sleep_duration=7200,
        light_sleep_duration=1800,
        awake_duration=600,
        description="良好的睡眠质量"
    )
    
    data = SleepMonitoringRecordData(
        states=[[1, "awake"], [2, "light_sleep"], [3, "deep_sleep"]],
        confidence=[[1, 0.9], [2, 0.8], [3, 0.85]],
        delta_ratio=[[1, 0.1], [2, 0.3], [3, 0.6]],
        theta_ratio=[[1, 0.2], [2, 0.4], [3, 0.4]],
        alpha_ratio=[[1, 0.3], [2, 0.2], [3, 0.1]],
        beta_ratio=[[1, 0.3], [2, 0.1], [3, 0.05]],
        gamma_ratio=[[1, 0.1], [2, 0.0], [3, 0.05]]
    )
    
    record = SleepMonitoringRecord(
        session_id="session_001",
        start_time=datetime.now() - timedelta(hours=8),
        end_time=datetime.now(),
        total_seconds=28800,
        summary=summary,
        data=data
    )
    
    # 创建记录
    record_id = repo.create_record(record)
    print(f"创建睡眠监测记录成功，ID: {record_id}")
    
    # 查询记录
    retrieved_record = repo.get_record_by_id("session_001")
    if retrieved_record:
        print(f"查询到记录: {retrieved_record.session_id}")
    
    # 获取所有记录
    all_records = repo.get_all_records(limit=10)
    print(f"总共有 {len(all_records)} 个睡眠监测记录")
    
    database.close()